package track_formats

import (
	"fmt"
	"github.com/pion/rtp"
	"gogs.smarteye.com/servere/gobvrtp/track"
)

func NewTrack(codec track.CodecId) (track.Track, bool) {
	newFn, ok := regTracks[codec]
	if !ok {
		return nil, false
	}

	objectTrack := newFn()

	return objectTrack, objectTrack != nil
}

type NewTrackFunc = func() track.Track

var regTracks = map[track.CodecId]NewTrackFunc{}

func RegisterTrack(codec track.CodecId, new NewTrackFunc) {
	regTracks[codec] = new
}

type baseTrack struct {
	track.DefaultTrack
}

func (c *baseTrack) onFrame(pkt *rtp.Packet, data []byte) {
	frame := &track.Frame{
		Codec: c.Codec(),
		Data:  data,
	}
	frame.PTS, _ = c.PacketPTS(pkt)
	frame.NTP, _ = c.PacketNTP(pkt)
	frame.Codec = c.Codec()
	c.CtlParma().OnFrame(c, frame)
}

// RTPMap implements Format.
func (c *baseTrack) RTPMap() string {
	return fmt.Sprintf("%v/%v", c.Codec(), c.ClockRate())
}

type AudioTrack struct {
	baseTrack
}

func (c *AudioTrack) SetChannel(channel int) *AudioTrack {
	c.CtlParma().SetChannel(channel)
	return c
}

// RTPMap implements Format.
func (c *AudioTrack) RTPMap() string {
	return fmt.Sprintf("%v/%v/%v", c.Codec(), c.ClockRate(), c.Channel())
}

type VideoTrack struct {
	baseTrack
}

type ApplicationTrack struct {
	baseTrack
}

// ToPtr returns a pointer copy of value.
func ToPtr[T any](x T) *T {
	return &x
}

// FromPtr returns the pointer value or empty.
func FromPtr[T any](x *T) T {
	if x == nil {
		return Empty[T]()
	}

	return *x
}

// Empty returns an empty value.
func Empty[T any]() T {
	var zero T
	return zero
}
